//////////////////////////////////////////////
// File				:	Mouse.h
//
// Author			:	Nick Faletra (NF)
//
// Date Created		:	12/22/2013
//////////////////////////////////////////////
#ifndef _JOYSTICK_H_
#define _JOYSTICK_H_

#include "InputDevice.h"

const int JOYSTICK_AXIS_RANGE	= 1024;
const float PERCENTAGE_RANGE	= 0.7f;
const int JOYSTICK_THRESHOLD	= (int)(JOYSTICK_AXIS_RANGE * PERCENTAGE_RANGE);
const float ONE_OVER_RANGE		= 1.f / (float)JOYSTICK_AXIS_RANGE;

enum Directions { DIR_LEFT = 0, DIR_RIGHT = 1, DIR_UP = 2, DIR_DOWN = 3, DIR_MAX };

class CJoystick : public CInputDevice
{
	char m_szJoyName[MAX_PATH];

	DIJOYSTATE2 m_diJoyState;
	DIJOYSTATE2 m_diPrevJoyState;

	int m_nNumButtons;
	bool m_bUnplugged;
	bool m_bXbox360Pad;
	bool m_bZAxisY;

	enum POV_dirs
	{
		POV_NEUTRAL		= -1,
		POV_UP			= 0,
		POV_UPRIGHT		= 45 * DI_DEGREES,
		POV_RIGHT		= 90 * DI_DEGREES,
		POV_DOWNRIGHT	= 135 * DI_DEGREES,
		POV_DOWN		= 180 * DI_DEGREES,
		POV_DOWNLEFT	= 225 * DI_DEGREES,
		POV_LEFT		= 270 * DI_DEGREES,
		POV_UPLEFT		= 315 * DI_DEGREES
	};

	bool TranslatePOV(int nDir, DWORD dwPOVDir);
	long TranslateRStickX(DIJOYSTATE2& diJoyState);
	long TranslateRStickY(DIJOYSTATE2& diJoyState);

public:
	CJoystick(IDirectInput8* pDI, HWND hWnd, const DIDEVICEINSTANCE* pdidi, bool bExclusive = false);

	bool ReadDevice();
	bool ReadBufferedDevice();

	void SwitchRStickAxes();

	bool ButtonDown(unsigned char ucButton);
	bool ButtonPressed(unsigned char ucButton);
	bool ButtonPressedEx(unsigned char ucButton);
	bool ButtonUp(unsigned char ucButton);
	bool ButtonReleased(unsigned char ucButton);
	bool ButtonReleasedEx(unsigned char ucButton);

	bool DPadDown(int nDir);
	bool DPadPressed(int nDir);
	bool DPadUp(int nDir);
	bool DPadReleased(int nDir);

	bool GetLStickDirDown(int nDir);
	bool GetLStickDirPressed(int nDir);

	int GetLStickXAmount();
	int GetLStickYAmount();
	float GetLStickXNormalized();
	float GetLStickYNormalized();

	bool GetRStickDirDown(int nDir);
	bool GetRStickDirPressed(int nDir);

	int GetRStickXAmount();
	int GetRStickYAmount();
	float GetRStickXNormalized();
	float GetRStickYNormalized();

	int GetLTriggerAmount();
	int GetRTriggerAmount();
	float GetLTriggerNormalized();
	float GetRTriggerNormalized();

	int CheckBufferedButtons();
	int CheckBufferedButtonsEx();

	__forceinline int GetNumButtons() const { return m_nNumButtons; }
	__forceinline bool GetUnplugged() const { return m_bUnplugged; }
	__forceinline const char* GetName() const { return (const char*)m_szJoyName; }
	__forceinline void SwapRStickAxes(const bool bSwapAxes) { m_bZAxisY = bSwapAxes; }
};

#endif // _JOYSTICK_H_